/*
 * Copyright (C) 2005-2007 Kevin Smith
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
USA
 *
 */

#ifndef SETSTATE_H
#define SETSTATE_H

#include "state.h"
#include "archive.h"
#include "solution.h"
#include "solver.h"

#include <qobject.h>

class SetState : public State
{

 public:
  enum PerturbationType { BasicPerturbation, DominatedRemovalBasic };

  /*!
   * Copy constructor.
   * Note that the new SetState is created with an empty newSolutions list.
   * This is because all the solutions are identical to those in the old.
   * set.
   */
  SetState(SetState&);

  /*!
   * Constructor which creates a set of solutions
   * \param params Number of parameters for each solution
   * \param objectives Number of objectives for each solution
   * \param setSize Number of initialsolutions to generate
	 * \param pqrs enables pqrs-style solution selection for perturbation in the set
   */
  SetState(uint params, uint objectives, uint setSize, Solver* problem, bool pqrs);

  /*!
   * Destructor
   */
  ~SetState();

	/*!
	 * Is PQRS enabled?
	 */
	bool pqrsEnabled();
	
  /*!
   * Returns the number of parameters set
   */
  uint getNumParams();

  /*!
   * Returns the number of objectives set
   */
  uint getNumObjectives();

  /*!
   * Returns the problem Solver in use
   */
  Solver* getProblem();

  /*!
   * Returns the new solutions generated, removing from the new solution
   * list as returned. Finally returns NULL;
   */
  Solution* getNewSolution();

  /*!
   * Returns the size of the set of solutions.
   */
  uint getSize();

  /*!
   * Sets the internal iterator setIterator back to the start of the
   * set list. Effectively resets the getNextsolution() method
   */
  void resetGetSolutionList();

  /*!
   * Returns solutions from the set, in order, returning NULL once the 
   * iterator has reached the end. The iterator is reset to the start
   * using resetGetSolutionList()
   */
  Solution* getNextSolution();

  /*!
   * Performs a perturbation on the set, of the type set by the other.
   */
  void perturb();

  /*!
   * This method returns the energy change generated by the last perturbation.
   * If there has not been a perturbation since the last time this method 
   * was called, the energy returned is zero.
   */
  double getEnergy();
  
  /*!
   * Sets the perturbation method for this state.
   */
  void setPerturbationType(PerturbationType t);

  /*!
   * Returns the enum of the PerturbationType in use. Necessary for the
   * copy constructor, but do not use yourself
   */
  PerturbationType getPerturbationType();

  void saveState(QString& fileNameStub);

  bool isDominatedBy(Solution& solution);
  
  double getMin(int obj);

  double getMax(int obj);

  void checkMinMax(Solution* sol);
 private:
  uint params;
  uint objectives;
  Solution** set;
  uint size, maxSize;
  //QPtrList<Solution> set;
  //QPtrListIterator<Solution> *setIterator;
  Solution* newSolution;
  uint newSize, newMaxSize;
  Solver* problem;
  PerturbationType perturbType;
  double lastEnergy;
  uint iterator;
  double *min;
  double *max;
	bool pqrs;

  void basicPerturbation();
  void basicDominatedPerturbation();
  void constructor(uint params, uint objectives, Solver* problem, bool pqrs);
  void allocSet(uint size);
  void growSet();
  void compactSet();
};

#endif
